package ro.ase.catalog.security.dao.hibernate;

import org.apache.log4j.Logger;
import org.hibernate.Transaction;
import org.hibernate.classic.Session;
import org.hibernate.exception.ConstraintViolationException;
import org.springframework.beans.factory.annotation.Autowired;
import ro.ase.catalog.beans.SchoolClass;
import ro.ase.catalog.beans.Teacher;
import ro.ase.catalog.beans.TeacherDisciplineClass;
import ro.ase.catalog.beans.User;
import ro.ase.catalog.beans.dto.TeacherDTO;
import ro.ase.catalog.dao.hibernate.GenericDAOImpl;
import ro.ase.catalog.security.dao.ITeacherDAO;
import ro.ase.catalog.security.dao.IUserDAO;

import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Ioana
 * Date: 5/12/14
 * Time: 9:37 PM
 * To change this template use File | Settings | File Templates.
 */
public class TeacherDAOImpl extends GenericDAOImpl<Teacher, Integer> implements ITeacherDAO {
    @Autowired
    private IUserDAO userDAO;
    private static final Logger logger = Logger.getLogger(TeacherDAOImpl.class);

    public Boolean saveTransactionalTeacher(User user, Teacher teacher) {
        Session session=null;
        Transaction transaction=null;
        Boolean success=true;
        try{
            session =getSessionFactory().openSession();
            transaction = session.beginTransaction();
            userDAO.save(user);
            save(teacher);
            transaction.commit();

        } catch(ConstraintViolationException e){
            try{
                transaction.rollback();
                logger.error("Tranzactia nu s-a putut realiza cu succes  "+e.getMessage());
                success=false;

            }
            catch(RuntimeException rbe){
                logger.error(rbe.getMessage());
                success=false;
            }
            throw e;
        } catch(RuntimeException e){
            try{
                transaction.rollback();
                logger.error("Tranzactia nu s-a putut realiza cu succes  "+e.getMessage());
                success=false;
            }
            catch(RuntimeException rbe){
                logger.error(rbe.getMessage());
                success=false;
            }
        } finally{
            if(session!=null){
                session.close();
            }
        }
        return success;
    }

    public Teacher getByLastNameFirstName(String lastName, String firstName) {
        List<Teacher> teacherList=getHibernateTemplate().find("select t from Teacher t where t.lastName = ? and t.firstName=?", new Object[]{lastName, firstName} );
       if(teacherList.size()>0)
        return teacherList.get(0);
        else
           return null;

    }

    public List<TeacherDTO> findByName(String searchName, int start, int limit) {
        List<TeacherDisciplineClass> disciplineList;
        if(searchName==null)
        {
            disciplineList=getHibernateTemplate().find("select tdc from TeacherDisciplineClass tdc ");
        }
        else{
            disciplineList=getHibernateTemplate().find("select tdc from TeacherDisciplineClass tdc where tdc.teacher.lastName = ?", searchName+"%");
        }    if(disciplineList.size()>0 ){
            List<TeacherDTO> teacherDTOs=new ArrayList<TeacherDTO>();
            for(int i=0;i<disciplineList.size();i++){
                TeacherDTO teacherDTO=new TeacherDTO();
                teacherDTO.setId(disciplineList.get(i).getTeacher().getId());
                teacherDTO.setFirstName(disciplineList.get(i).getTeacher().getFirstName());
                teacherDTO.setLastName(disciplineList.get(i).getTeacher().getLastName());
                teacherDTO.setDiscipline(disciplineList.get(i).getDiscipline().getName());
                if(disciplineList.get(i).getTeacher().getClassMaster()!=null)   {
                    teacherDTO.setClassMaster(disciplineList.get(i).getTeacher().getClassMaster().getName());
                }
                teacherDTO.setUserName(disciplineList.get(i).getTeacher().getUser().getLoginname());
                teacherDTOs.add(teacherDTO);
            }
            return  teacherDTOs;
        }
        return null;
    }

    public void deleteTeacherTransactional(Teacher teacher, User user) {
        Session session=null;
        Transaction transaction=null;
        Boolean success=true;
        try{
            session =getSessionFactory().openSession();
            transaction = session.beginTransaction();
            userDAO.delete(user);
            delete(teacher);
            transaction.commit();

        } catch(ConstraintViolationException e){
            try{
                transaction.rollback();
                logger.error("Tranzactia nu s-a putut realiza cu succes  "+e.getMessage());
                success=false;

            }
            catch(RuntimeException rbe){
                logger.error(rbe.getMessage());
                success=false;
            }
            throw e;
        } catch(RuntimeException e){
            try{
                transaction.rollback();
                logger.error("Tranzactia nu s-a putut realiza cu succes  "+e.getMessage());
                success=false;
            }
            catch(RuntimeException rbe){
                logger.error(rbe.getMessage());
                success=false;
            }
        } finally{
            if(session!=null){
                session.close();
            }
        }
    }

    public Teacher findByUserName(String userName) {
        List<Teacher> teacherList=getHibernateTemplate().find("Select t from Teacher t where t.user.loginname = ?", userName);
        if(teacherList.size()>0)
        return teacherList.get(0);
        else return null;
    }

    public List<Teacher> getAllTeacherFromAClass(SchoolClass classMaster) {
        List<Teacher> teacherList=getHibernateTemplate().find("Select tdc.teacher from TeacherDisciplineClass tdc where tdc.aSchoolClass = ?", classMaster);
        if(teacherList.size()>0)
            return teacherList;
        else return null;
    }
}
